package com.ruoyi.system.service.impl;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.system.mapper.JobMapper;
import com.ruoyi.system.domain.Job;
import com.ruoyi.system.domain.Seeker;
import com.ruoyi.system.service.IJobService;


import java.util.Date;
import java.text.ParseException;
import java.text.SimpleDateFormat;
/**
 * 职位信息管理Service业务层处理
 * 
 * @author ruoyi
 * @date 2024-05-22
 */
@Service
public class JobServiceImpl implements IJobService 
{
    @Autowired
    private JobMapper jobMapper;

    /**
     * 查询职位信息管理
     * 
     * @param jobId 职位信息管理主键
     * @return 职位信息管理
     */
    @Override
    public Job selectJobByJobId(Long jobId)
    {
        return jobMapper.selectJobByJobId(jobId);
    }

    /**
     * 查询职位信息管理列表
     * 
     * @param job 职位信息管理
     * @return 职位信息管理
     */
    @Override
    public List<Job> selectJobList(Job job)
    {
        return jobMapper.selectJobList(job);
    }

    /**
     * 新增职位信息管理
     * 
     * @param job 职位信息管理
     * @return 结果
     */
    @Override
    public int insertJob(Job job)
    {
        return jobMapper.insertJob(job);
    }

    /**
     * 修改职位信息管理
     * 
     * @param job 职位信息管理
     * @return 结果
     */
    @Override
    public int updateJob(Job job)
    {
        return jobMapper.updateJob(job);
    }

    /**
     * 批量删除职位信息管理
     * 
     * @param jobIds 需要删除的职位信息管理主键
     * @return 结果
     */
    @Override
    public int deleteJobByJobIds(Long[] jobIds)
    {
        return jobMapper.deleteJobByJobIds(jobIds);
    }

    /**
     * 删除职位信息管理信息
     * 
     * @param jobId 职位信息管理主键
     * @return 结果
     */
    @Override
    public int deleteJobByJobId(Long jobId)
    {
        return jobMapper.deleteJobByJobId(jobId);
    }

        /**
     * 职位推荐算法排序
     */

         @Override
        public List<Job> selectRecommendedJobs(Seeker seeker) {
        // 查询所有职位
        Job job = new Job();
        List<Job> jobs = jobMapper.selectJobList(job);
        
        // 设置权重值，可以根据实际需求调整
        Map<String, Double> weights = new HashMap<>();
        weights.put("jobName", 0.7);
        // weights.put("jobKind", 0.01);
        weights.put("jobWorkaddr", 0.1);
        weights.put("jobSalrange", 0.1);
        // weights.put("jobWorkexp", 0.1);

        // 加权推荐
        List<Job> recommendations = weightedRecommendation(seeker, jobs, weights);

        // 确保返回至少10条数据
        return recommendations;
    }




    @Override
    public List<Job> weightedRecommendation(Seeker seeker, List<Job> jobs, Map<String, Double> weights) {
    List<Job> recommendations = new ArrayList<>();

    for (Job job : jobs) {
        double score = 0;

        // 使用字符串相似度计算
        double jobNameSimilarity = calculateStringSimilarity(job.getJobName(), seeker.getSeekerExppos());
        // double jobKindSimilarity = calculateStringSimilarity(job.getJobKind(), seeker.getSeekerExpjobtype());
        double jobWorkaddrSimilarity = calculateStringSimilarity(job.getJobWorkaddr(), seeker.getSeekerExpworkloc());

        // 薪资范围比较
        double jobSalrangeSimilarity = compareSalaryRanges(seeker.getSeekerExpsal(), job.getJobSalrange());

        // 工作经验比较
        // double jobWorkexpSimilarity = compareWorkExperience(seeker.getSeekerWorkexp(), job.getJobWorkexp());

        // 加权得分综合
        score += weights.get("jobName") * jobNameSimilarity;
        // score += weights.get("jobKind") * jobKindSimilarity;
        score += weights.get("jobWorkaddr") * jobWorkaddrSimilarity;
        score += weights.get("jobSalrange") * jobSalrangeSimilarity;
        // score += weights.get("jobWorkexp") * jobWorkexpSimilarity;

        job.setScore(score);
        recommendations.add(job);
    }

    // 根据加权的得分进行推荐排序
    recommendations.sort((j1, j2) -> Double.compare(j2.getScore(), j1.getScore()));

    return recommendations;
}

// 比较薪资范围的辅助方法
private double compareSalaryRanges(String seekerSalary, String jobSalary) {
    try {
        double seekerMinSalary = Double.parseDouble(seekerSalary.split("k-")[0]);
        double jobMinSalary = Double.parseDouble(jobSalary.split("k-")[0]);
        return jobMinSalary >= seekerMinSalary ? 1 : 0;
    } catch (Exception e) {
        return 0;
    }
}

// 比较搜索薪资范围的辅助方法
private double compareSalary(String searchSalary, String jobSalary) {
    try {
        double seekerMinSalary = Double.parseDouble(searchSalary);
        double jobMinSalary = Double.parseDouble(jobSalary.split("k-")[0]);
        return jobMinSalary >= seekerMinSalary ? 1 : 0;
    } catch (Exception e) {
        return 0;
    }
}

// 比较工作经验的辅助方法
// private double compareWorkExperience(String seekerExperience, String jobExperience) {
//     // 具体实现可以根据实际的工作经验字段格式进行调整
//     return jobExperience.contains(seekerExperience) ? 1 : 0;
// }

private double calculateStringSimilarity(String str1, String str2) {
        // 如果 str1 包含 str2 或 str2 包含 str1，增加相似度
        if (str1.contains(str2) || str2.contains(str1)) {
            return 1;
        }

        
    int len1 = str1.length();
    int len2 = str2.length();

    // 创建一个二维数组来存储每一步的编辑距离
    int[][] dp = new int[len1 + 1][len2 + 1];

    // 初始化第一行和第一列
    for (int i = 0; i <= len1; i++) {
        dp[i][0] = i;
    }
    for (int j = 0; j <= len2; j++) {
        dp[0][j] = j;
    }

    // 填充dp数组
    for (int i = 1; i <= len1; i++) {
        for (int j = 1; j <= len2; j++) {
            int cost = (str1.charAt(i - 1) == str2.charAt(j - 1)) ? 0 : 1;
            dp[i][j] = Math.min(Math.min(dp[i - 1][j] + 1, dp[i][j - 1] + 1), dp[i - 1][j - 1] + cost);
        }
    }

    // 计算相似度
    int distance = dp[len1][len2];
    int maxLength = Math.max(len1, len2);
    return 1.0 - (double) distance / maxLength;
}


@Override
public List<Job> SearchRecommendedJobs(Job searchCriteria)  {
        // 查询所有职位
Job job = new Job();
List<Job> jobs = jobMapper.selectJobList(job);

// 设置权重值，可以根据实际需求调整
Map<String, Double> weights = new HashMap<>();
weights.put("jobName", 0.4);
weights.put("jobWorkaddr", 0.2);
weights.put("jobSalrange", 0.15);
weights.put("jobDesc", 0.05);
weights.put("jobWorkexp", 0.05);
weights.put("jobPoststat", 0.05);
weights.put("jobEdureq", 0.05);
weights.put("jobInfoupdatetime", 0.05);

// 加权推荐
List<Job> recommendations = weightedRecommendationBySearch(searchCriteria, jobs, weights);


return recommendations;

}


@Override
public List<Job> weightedRecommendationBySearch(Job searchCriteria, List<Job> jobs, Map<String, Double> initialWeights) {
    List<Job> recommendations = new ArrayList<>();
    Map<String, Double> weights = new HashMap<>(initialWeights);

    // 计算实际权重，根据非空属性重新分配权重
    double totalWeight = 0;
    for (Map.Entry<String, Double> entry : initialWeights.entrySet()) {
        String key = entry.getKey();
        if (isFieldEmpty(searchCriteria, key)) {
            weights.put(key, 0.0);
        } else {
            totalWeight += entry.getValue();
        }
    }
    for (Map.Entry<String, Double> entry : weights.entrySet()) {
        if (entry.getValue() != 0) {
            weights.put(entry.getKey(), entry.getValue() / totalWeight);
        }
    }

    for (Job job : jobs) {
        double score = 0;

        // 使用字符串相似度计算
        double jobNameSimilarity = (searchCriteria.getJobName() == null || searchCriteria.getJobName().isEmpty()) ? 1 : calculateStringSimilarity(job.getJobName(), searchCriteria.getJobName());
        double jobWorkaddrSimilarity = (searchCriteria.getJobWorkaddr() == null || searchCriteria.getJobWorkaddr().isEmpty()) ? 1 : calculateStringSimilarity(job.getJobWorkaddr(), searchCriteria.getJobWorkaddr());
        double jobDescSimilarity = (searchCriteria.getJobDesc() == null || searchCriteria.getJobDesc().isEmpty()) ? 1 : calculateStringSimilarity(job.getJobDesc(), searchCriteria.getJobDesc());

        // 相等比较
        double jobPoststatSimilarity = (searchCriteria.getJobPoststat() == null || searchCriteria.getJobPoststat().isEmpty()) ? 1 : job.getJobPoststat().equals(searchCriteria.getJobPoststat()) ? 1 : 0;
        double jobEdureqSimilarity = (searchCriteria.getJobEdureq() == null || searchCriteria.getJobEdureq().isEmpty()) ? 1 : job.getJobEdureq().equals(searchCriteria.getJobEdureq()) ? 1 : 0;

        // 更新时间比较
        double jobInfoupdatetimeSimilarity = (searchCriteria.getJobInfoupdatetime() == null || searchCriteria.getJobInfoupdatetime().isEmpty()) ? 0 : calculateUpdateTimeSimilarity(job.getJobInfoupdatetime(), searchCriteria.getJobInfoupdatetime());

        // 薪资范围比较
        double jobSalrangeSimilarity = (searchCriteria.getJobSalrange() == null || searchCriteria.getJobSalrange().isEmpty()) ? 1 : compareSalary(searchCriteria.getJobSalrange(), job.getJobSalrange());

        // 工作经验比较
        double jobWorkexpSimilarity = (searchCriteria.getJobWorkexp() == null || searchCriteria.getJobWorkexp().isEmpty()) ? 1 : compareWorkExperience(searchCriteria.getJobWorkexp(), job.getJobWorkexp());

        // 加权得分综合
        score += weights.get("jobName") * jobNameSimilarity;
        score += weights.get("jobWorkaddr") * jobWorkaddrSimilarity;
        score += weights.get("jobSalrange") * jobSalrangeSimilarity;
        score += weights.get("jobDesc") * jobDescSimilarity;
        score += weights.get("jobWorkexp") * jobWorkexpSimilarity;
        score += weights.get("jobPoststat") * jobPoststatSimilarity;
        score += weights.get("jobEdureq") * jobEdureqSimilarity;
        score += weights.get("jobInfoupdatetime") * jobInfoupdatetimeSimilarity;

        job.setScore(score);
        recommendations.add(job);
    }

    // 根据加权的得分进行推荐排序
    recommendations.sort((j1, j2) -> Double.compare(j2.getScore(), j1.getScore()));

    return recommendations;
}

// 辅助方法：检查字段是否为空
private boolean isFieldEmpty(Job job, String fieldName) {
    switch (fieldName) {
        case "jobName":
            return job.getJobName() == null || job.getJobName().isEmpty();
        case "jobWorkaddr":
            return job.getJobWorkaddr() == null || job.getJobWorkaddr().isEmpty();
        case "jobSalrange":
            return job.getJobSalrange() == null || job.getJobSalrange().isEmpty();
        case "jobDesc":
            return job.getJobDesc() == null || job.getJobDesc().isEmpty();
        case "jobWorkexp":
            return job.getJobWorkexp() == null || job.getJobWorkexp().isEmpty();
        case "jobPoststat":
            return job.getJobPoststat() == null || job.getJobPoststat().isEmpty();
        case "jobEdureq":
            return job.getJobEdureq() == null || job.getJobEdureq().isEmpty();
        case "jobInfoupdatetime":
            return job.getJobInfoupdatetime() == null || job.getJobInfoupdatetime().isEmpty();
        default:
            return true;
    }
}


// 比较工作经验的辅助方法
private double compareWorkExperience(String searchExp, String jobExp) {
    if (searchExp == null || jobExp == null) {
        return 0;
    }
    Map<String, Integer> expMap = new HashMap<>();
    expMap.put("应届生", 0);
    expMap.put("实习生", 0);
    expMap.put("1年以内", 1);
    expMap.put("1-3年", 3);
    expMap.put("3-5年", 5);
    expMap.put("5-10年", 10);
    expMap.put("10年以上", 11);

    Integer searchVal = expMap.get(searchExp);
    Integer jobVal = expMap.get(jobExp);

    if (searchVal != null && jobVal != null) {
        if (searchExp.equals("1年以内")) {
            return (jobExp.contains("1年以内") || (jobExp.contains("年以上") && jobVal <= 1)) ? 1 : 0;
        } else if (searchExp.equals("1-3年")) {
            return (jobExp.equals(searchExp) || (jobExp.contains("年以上") && jobVal <= 3) || 
                    (jobExp.contains("-") && Integer.parseInt(jobExp.split("-")[1].replace("年", "")) <= 3)) ? 1 : 0;
        } else if (searchExp.equals("3-5年")) {
            return (jobExp.equals(searchExp) || (jobExp.contains("年以上") && jobVal <= 5) || 
                    (jobExp.contains("-") && Integer.parseInt(jobExp.split("-")[1].replace("年", "")) <= 5)) ? 1 : 0;
        } else if (searchExp.equals("5-10年")) {
            return (jobExp.equals(searchExp) || (jobExp.contains("年以上") && jobVal <= 10) || 
                    (jobExp.contains("-") && Integer.parseInt(jobExp.split("-")[1].replace("年", "")) <= 10)) ? 1 : 0;
        } else if (searchExp.equals("10年以上")) {
            return (jobExp.contains("年以上") || 
                    (jobExp.contains("-") && Integer.parseInt(jobExp.split("-")[1].replace("年", "")) <= 1000)) ? 1 : 0;
        } else {
            return searchExp.equals(jobExp) ? 1 : 0;
        }
    }
    return 0;
}

private double calculateUpdateTimeSimilarity(String jobTime, String searchTime) {
    // 获取当前时间的时间戳
    long currentTime = System.currentTimeMillis();

    // 将jobTime转换为时间戳
    long jobTimeStamp = parseDateToTimestamp(jobTime);

    // 基于搜索条件的更新时间范围计算相似度
    switch (searchTime) {
        case "一天以内":
            return jobTimeStamp >= (currentTime - 24 * 60 * 60 * 1000L) ? 1.0 : 0.0;
        case "三天以内":
            return jobTimeStamp >= (currentTime - 3 * 24 * 60 * 60 * 1000L) ? 1.0 : 0.0;
        case "一周以内":
            return jobTimeStamp >= (currentTime - 7 * 24 * 60 * 60 * 1000L) ? 1.0 : 0.0;
        case "一个月以内":
            return jobTimeStamp >= (currentTime - 30 * 24 * 60 * 60 * 1000L) ? 1.0 : 0.0;
        case "一年以内":
            return jobTimeStamp >= (currentTime - 365 * 24 * 60 * 60 * 1000L) ? 1.0 : 0.0;
        default:
            return 0.0;
    }
}

private long parseDateToTimestamp(String date) {
    try {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date parsedDate = dateFormat.parse(date);
        return parsedDate.getTime();
    } catch (ParseException e) {
        e.printStackTrace();
    }
    return 0;
}
}
